package com.zuipin.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.zuipin.entity.SQLColumn;
import com.zuipin.mapper.GeneralMapper;
import com.zuipin.service.ICrudService;
import com.zuipin.util.GeneralMapperReflectUtil;
import com.zuipin.util.PersistentUtil;

/**
 * 
 * @author xjd
 *
 */
@Service("crudService")
public class CrudServiceImpl implements ICrudService {
	
	@Resource
	private GeneralMapper generalMapper;
	
	@Override
	public <T> T selectByPrimaryKey(Class<T> clazz, Object primaryValue) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		
		String tableName = PersistentUtil.getTableName(clazz);
		String primaryKey = PersistentUtil.getPrimaryKey(clazz);
		List<String> queryColumn = GeneralMapperReflectUtil.getAllColumnNames(clazz);
		
		param.put("tableName", tableName);
		param.put("primaryKey", primaryKey);
		param.put("primaryValue", primaryValue);
		param.put("queryColumn", queryColumn);
		return GeneralMapperReflectUtil.parseToBean(generalMapper.selectByPrimaryKey(param), clazz);
	}
	
	@Override
	public <T> int insertSelective(T t) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		
		Class<?> clazz = t.getClass();
		
		String tableName = PersistentUtil.getTableName(clazz);
		// List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getSQLColumnsExceptNull(t);
		List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getSQLColumns(t, false, false, true, true);
		param.put("tableName", tableName);
		param.put("SQLColumns", SQLColumns);
		return generalMapper.insert(param);
	}
	
	@Override
	public <T> int insert(T t) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		
		Class<?> clazz = t.getClass();
		
		String tableName = PersistentUtil.getTableName(clazz);
		// List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getAllSQLColumns(t);
		// SQLColumns = PersistentUtil.excludePK(SQLColumns);
		List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getSQLColumns(t, false, true, true, true);
		param.put("tableName", tableName);
		param.put("SQLColumns", SQLColumns);
		return generalMapper.insert(param);
	}
	
	@Override
	public <T> int insertBatch(List<T> list) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		
		String tableName = "";
		List<String> columnNames = new ArrayList<String>();
		
		List<List<SQLColumn>> dataList = new ArrayList<List<SQLColumn>>(list.size() + 1);
		
		for (T t : list) {
			if (tableName.equals("")) {
				Class<?> clazz = t.getClass();
				tableName = PersistentUtil.getTableName(clazz);
			}
			if (columnNames.size() == 0) {
				Class<?> clazz = t.getClass();
				columnNames = GeneralMapperReflectUtil.getAllColumnNames(clazz);
			}
			List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getAllSQLColumns(t);
			SQLColumns = PersistentUtil.excludePK(SQLColumns);
			dataList.add(SQLColumns);
		}
		param.put("tableName", tableName);
		param.put("columnNames", columnNames);
		param.put("dataList", dataList);
		return generalMapper.insertBatch(param);
	}
	
	@Override
	public <T> int deleteByPrimaryKey(Class<T> clazz, Object primaryValue) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		String tableName = PersistentUtil.getTableName(clazz);
		String primaryKey = PersistentUtil.getPrimaryKey(clazz);
		param.put("tableName", tableName);
		param.put("primaryKey", primaryKey);
		param.put("primaryValue", primaryValue);
		return generalMapper.deleteByPrimaryKey(param);
	}
	
	@Override
	public <T> int updateByPrimaryKey(T t) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		Class<?> clazz = t.getClass();
		String tableName = PersistentUtil.getTableName(clazz);
		String primaryKey = PersistentUtil.getPrimaryKey(clazz);
		List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getSQLColumns(t, false, true, false, true);
		Object primaryValue = GeneralMapperReflectUtil.getPrimaryValue(t);
		param.put("tableName", tableName);
		param.put("primaryKey", primaryKey);
		param.put("primaryValue", primaryValue);
		param.put("SQLColumns", SQLColumns);
		return generalMapper.updateByPrimaryKey(param);
	}
	
	@Override
	public <T> int updateByPrimaryKeySelective(T t) throws Exception {
		Map<String, Object> param = new HashMap<String, Object>();
		Class<?> clazz = t.getClass();
		String tableName = PersistentUtil.getTableName(clazz);
		String primaryKey = PersistentUtil.getPrimaryKey(clazz);
		List<SQLColumn> SQLColumns = GeneralMapperReflectUtil.getSQLColumns(t, false, false, false, true);
		Object primaryValue = GeneralMapperReflectUtil.getPrimaryValue(t);
		param.put("tableName", tableName);
		param.put("primaryKey", primaryKey);
		param.put("primaryValue", primaryValue);
		param.put("SQLColumns", SQLColumns);
		return generalMapper.updateByPrimaryKey(param);
	}
	
}
